package com.mimosa.common.system.permission;

import java.awt.MenuItem;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import javax.annotation.Resource;

import org.apache.commons.lang3.StringUtils;
import org.hibernate.criterion.Criterion;
import org.hibernate.criterion.Disjunction;
import org.hibernate.criterion.Restrictions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;

import com.mimosa.common.dao.HibernateDao;
import com.mimosa.common.service.CommonService;
import com.mimosa.common.system.department.TDepartmentDao;
import com.mimosa.common.system.role.TRole;
import com.mimosa.common.system.role.TUserRole;
import com.mimosa.common.system.role.TUserRoleDao;
import com.mimosa.common.system.role.UserRoleService;
import com.mimosa.common.system.user.TUser;
import com.mimosa.util.config.YesNoType;
import com.mimosa.util.constant.StringConstUtil;

@Service
@Transactional
public class PermissionService extends CommonService<TPermission, String> {
	@Autowired
	private TPermissionDao rolePermissionDao;
	@Autowired
	private TUserRoleDao userRoleDao;
	@Resource
	private UserRoleService userRoleService;

	/**
	 * 保存角色权限数据
	 * 
	 * @param rolePermission
	 */
	public void saveTRolePermission(TRole role, PermissionType permissionType, String[] strids) {
		// 首先删除所有的关联
		String hql = "from TPermission where ROLEORUSERID = ? and itemType=?";
		List<TPermission> TRolePermissionList = rolePermissionDao.find(hql, role.getId().trim(),
				permissionType.ordinal());
		if (TRolePermissionList != null && TRolePermissionList.size() > 0) {
			for (int x = 0; x < TRolePermissionList.size(); x++) {
				TPermission tRolePermission = TRolePermissionList.get(x);
				rolePermissionDao.delete(tRolePermission);
			}
		}
		// 重新关联
		for (int x = 0; x < strids.length; x++) {
			String strid = strids[x];
			TPermission rolePermission = new TPermission();
			rolePermission.setRoleOrUserId(role.getId()); // 设置权限和角色相关联
			rolePermission.setUserFlag(YesNoType.N.name()); // 非用户标识
			rolePermission.setItemType(permissionType.name()); // 设置主题类型
			rolePermission.setItemId(strid); // 设置主题id对应的是菜单表中的主键（设置成了固定的）
			rolePermissionDao.save(rolePermission);
		}
	}

	/**
	 * 保存关联关系
	 * 
	 * @param rid
	 * @param menuIds
	 * @param iType
	 */
	private void saveRole2ItemId(String rid, String[] menuIds, String iType) {
		List<TPermission> TPermissionList = this.rolePermissionDao
				.find("from TPermission r where r.roleOrUserId =? and r.itemType =?", rid, iType);
		if (TPermissionList != null && TPermissionList.size() > 0) {
			for (TPermission rolePermission : TPermissionList)
				this.rolePermissionDao.delete(rolePermission);
		}
		for (String menuId : menuIds) {
			if (StringUtils.isNotBlank(menuId)) {
				TPermission rolePermission = new TPermission(rid, menuId, iType);
				super.saveEntity(rolePermission);
			}
		}

	}

	/**
	 * 保存权限信息
	 * 
	 * @param rid
	 *            角色id
	 * @param menuIds
	 * @param iType
	 */
	public void saveRole2MenuId(String rid, String[] menuIds, String iType) {
		this.saveRole2ItemId(rid, menuIds, iType);
	}

	/**
	 * 建立角色和主题之间的关联关系
	 * 
	 * @param roles
	 *            角色
	 * @param cates
	 *            主题
	 */
	public void saveCategoryCustomByCidUid(String roles, String cates) {
		String[] rIds = roles.split(",");
		Criterion ucriterion = null;
		Criterion icriterion = null;
		for (String rid : rIds) {
			ucriterion = Restrictions.eq("roleOrUserId", rid);
			icriterion = Restrictions.eq("itemType", PermissionType.CATEGORY.ordinal()); // 1
			List<TPermission> ttcate = this.rolePermissionDao.find(ucriterion, icriterion);
			for (TPermission tRolePermission : ttcate) {
				this.rolePermissionDao.delete(tRolePermission);
			}

			//
		}
		// 建立新关系
		String[] cateIds = cates.split(",");
		for (String rid : rIds) {
			for (String cid : cateIds) {
				TPermission tRolePermission = new TPermission(rid, cid, PermissionType.CATEGORY.name());
				this.rolePermissionDao.save(tRolePermission);
			}
		}
	}

	/**
	 * 根据角色id和类型获取权限表
	 * 
	 * @param rid
	 *            角色id
	 * @param ordinal
	 *            权限类型
	 * @return
	 */
	public List<TPermission> getPerByRid2type(String rid, String ordinal) {
		return this.rolePermissionDao.getPerByRid2type(rid, ordinal);
	}

	/**
	 * 根据角色id和类型获取权限表
	 * 
	 * @param uid
	 *            用户id
	 * @param ordinal
	 *            权限类型
	 * @return
	 */
	public List<TPermission> getPerByUid2type(String uid, String ordinal) {
		return this.rolePermissionDao.getByUid2type(uid, ordinal);
	}

	@Autowired
	private TDepartmentDao departmentDao;

	/**
	 * 获取部门相关的权限信息
	 * 
	 * @param departId
	 *            部门标识
	 * @param itemType
	 *            权限类型
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public List<TPermission> getDepartPermissionList(String departId, String itemType) {
		List<TPermission> permissionList = Collections.EMPTY_LIST;
		if (StringUtils.isNotBlank(departId)) {
			List<String> depIds = this.departmentDao.getParentDepartIds(departId);
			depIds.add(departId);
			permissionList = this.rolePermissionDao.find(Restrictions.eq("itemType", itemType),
					Restrictions.in("roleOrUserId", depIds));
		}

		return permissionList;
	}

	/**
	 * 获取用户的数据库权限集合，并将数据库的名称信息以字符串的形式返回，多个名称用逗号进行分隔
	 * 
	 * @param uid
	 *            用户的主键信息
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public List<TPermission> getUserDatabasePermission(TUser user) {
		List<TPermission> permissionList = Collections.EMPTY_LIST;
		if (user != null) {
			Criterion userCri = Restrictions.eq("roleOrUserId", user.getId());
			Criterion typeCri = Restrictions.eq("itemType", PermissionType.DATABASE.name());
			if (StringUtils.isNotBlank(user.getDepartmentId())) {
				List<String> depIds = this.departmentDao.getParentDepartIds(user.getDepartmentId());
				depIds.add(user.getDepartmentId());

				Disjunction junction = Restrictions.disjunction();
				junction.add(userCri);
				junction.add(Restrictions.in("roleOrUserId", depIds));
				permissionList = this.rolePermissionDao.find(junction, typeCri);
			} else {
				permissionList = this.rolePermissionDao.find(userCri, typeCri);
			}
		}
		return permissionList;
	}

	/**
	 * 保存角色和聚类关联关系
	 * 
	 * @param roleid
	 *            角色id
	 * @param clusids
	 *            聚类id
	 * @param ordinal
	 *            权限类型
	 */
	public void saveRole2ClusId(String roleid, String clusids, String itemType) {
		String[] cids = clusids.split(",");
		this.saveRole2ItemId(roleid, cids, itemType);
	}

	/**
	 * 保存权限关系
	 * 
	 * @param roleid
	 *            角色id
	 * @param clusids
	 *            聚类id
	 * @param ordinal
	 *            权限类型
	 */
	public void savePermission(String roleOrUserIds, String itemIds, String itemType, String userFlag) {
		Assert.notNull(itemIds);
		Assert.notNull(roleOrUserIds);
		Assert.notNull(itemType);
		Assert.notNull(userFlag);

		String[] itemIdArrays = StringUtils.split(itemIds, StringConstUtil.COMMA);
		String[] roleOrUserIdArrays = StringUtils.split(roleOrUserIds, StringConstUtil.COMMA);
		TPermission permission = null;
		if (itemIdArrays.length < roleOrUserIdArrays.length) {
			for (String itemId : itemIdArrays) {
				for (String ruId : roleOrUserIdArrays) {
					permission = new TPermission();
					permission.setItemId(itemId);
					permission.setItemType(itemType);

					permission.setRoleOrUserId(ruId);
					permission.setUserFlag(userFlag);

					this.rolePermissionDao.save(permission);
				}
			}
		} else {
			for (String ruId : roleOrUserIdArrays) {
				for (String itemId : itemIdArrays) {
					permission = new TPermission();
					permission.setItemId(itemId);
					permission.setItemType(itemType);

					permission.setRoleOrUserId(ruId);
					permission.setUserFlag(userFlag);

					this.rolePermissionDao.save(permission);
				}
			}
		}
	}

	/**
	 * 删除权限信息
	 * 
	 * @param roleOrUserIds
	 *            角色或用户列表
	 * @param itemIds
	 *            权限类的主键
	 */
	public void deletePermission(String roleOrUserIds, String itemIds) {
		Assert.notNull(itemIds);
		Assert.notNull(roleOrUserIds);

		String[] itemIdArrays = StringUtils.split(itemIds, StringConstUtil.COMMA);
		String[] roleOrUserIdArrays = StringUtils.split(roleOrUserIds, StringConstUtil.COMMA);
		if (itemIdArrays.length < roleOrUserIdArrays.length) {
			for (String itemId : itemIdArrays) {
				for (String ruId : roleOrUserIdArrays) {
					this.rolePermissionDao.deleteByCompositeKey(itemId, ruId);
				}
			}
		} else {
			for (String ruId : roleOrUserIdArrays) {
				for (String itemId : itemIdArrays) {
					this.rolePermissionDao.deleteByCompositeKey(itemId, ruId);
				}
			}
		}
	}

	/**
	 * 根据角色id获取所有的权限id
	 * 
	 * @param roleid
	 *            角色id
	 * @param ordinal
	 *            角色类型
	 * @return
	 */
	public List<String> getItemByRid2type(String roleid, String ordinal) {
		return this.rolePermissionDao.getItemByRid2type(roleid, ordinal);
	}

	/**
	 * 根据用户id获取所有的权限ids
	 * 
	 * @param roleid
	 *            用户id
	 * @param ordinal
	 * @return
	 */
	public List<String> getItemByUid2type(String userid, String ordinal) {
		return this.rolePermissionDao.getItemByUid2type(userid, ordinal);
	}

	/**
	 * 根据用户id获取所有的权限ids
	 * 
	 * @param roleid
	 *            用户id
	 * @param ordinal
	 * @return
	 */
	public List<MenuItem> getItemByUid2Manager(String userid, String idPrefix, String ordinal) {
		return this.rolePermissionDao.getItemByUid2Manager(userid, idPrefix, ordinal);
	}

	/**
	 * 根据用户id获取对应的权限ids
	 * 
	 * @param id
	 *            用户id
	 * @return 权限ids
	 */
	public List<String> getItemsByUid(String id) {
		List<String> itemsIds = new ArrayList<String>();
		List<TUserRole> userRoles = this.userRoleDao.find("from TUserRole u where u.userId = ?", id);
		for (TUserRole tUserRole : userRoles) {
			String roleid = tUserRole.getRoleId();
			List<TPermission> trpList = this.rolePermissionDao.find("from TPermission r where r.roleOrUserId = ?",
					roleid);
			for (TPermission tRolePermission : trpList) {
				itemsIds.add(tRolePermission.getItemId());
			}
		}
		return itemsIds;
	}

	@Override
	protected HibernateDao<TPermission, String> getHibernateDao() {
		return this.rolePermissionDao;
	}
}
